package cat.joronya.supermanager.service.substrImpl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

import android.content.ContentValues;
import android.util.Log;
import cat.joronya.supermanager.Supermanager;
import cat.joronya.supermanager.service.NextMatchesParser;

public class NextMatchesParserImpl implements NextMatchesParser
{
	// start table day
	private static final String START_COMPETITION_TABLE = "<div class=\"tituloprox\">";
	private static final String STOP_COMPETITION_TABLE = "<div class=\"pieprox\">";
	
	private static final String START_DAY = " - Jornada <b>";
	private static final String STOP_DAY = "</b></div>";
	
	// start match tr
	private static final String START_DAY_TR = "<tr>";
	private static final String STOP_DAY_TR = "</tr>";
	
	// start teams td
	private static final String START_TEAMS = "<td class=\"oscuro2\" width=\"280\">";
	private static final String STOP_TEAMS = "</td>";
	
	// start date td
	private static final String START_DATE = "<td class=\"claro\" width=\"95\">";
	private static final String STOP_DATE = "</td>";
	
	// start time td
	private static final String START_TIME = "<td class=\"oscuro\" width=\"50\">";
	private static final String STOP_TIME = " h.</td>";
	
	// start retransmissions td
	private static final String START_RETRANSMISSIONS = "<td class=\"claro\" width=\"138\">";
	private static final String STOP_RETRANSMISSIONS = "</td>";
	
	// start retransmission a
	private static final String START_RETRANSMISSION_B = "<b>";
	private static final String STOP_RETRANSMISSION_B = "</b>";
	
	// matches hashtable
	private ArrayList<ContentValues> matches = new ArrayList<ContentValues>();
	
	// days hashtable, per saber quins dies hem de borrar abans de insertar de nou
	private HashSet<Integer> days = new HashSet<Integer>();

	public long parse(String html) throws Exception 
	{
		long start = System.nanoTime();

		try
		{
			int competitionStart = html.indexOf(START_COMPETITION_TABLE);
			if( competitionStart == -1 )
				throw new Exception();
			
			int competitionStop, jornadaStart, jornadaStop, trStart, trStop, matchStart, matchStop, 
				dateStart, dateStop, timeStart, timeStop, retransmissionStart, retransmissionStop, 
				retransmissionBStart, retransmissionBStop;
			String competition, day, homeTeam, vsTeam, matchDate, matchTime, retransmissionsTd;
			ArrayList<String> retransmissions;
			Timestamp matchTimestamp = null;
			
			// mentres tinguem noves taules de competition
			while( competitionStart != -1 )
			{
				// competition table
				competitionStop = html.indexOf(STOP_COMPETITION_TABLE, competitionStart+STOP_COMPETITION_TABLE.length());
				String competitionTable = html.substring(competitionStart+START_COMPETITION_TABLE.length(), competitionStop);
				
				// parsejem competicio i jornada
				jornadaStart = competitionTable.indexOf(START_DAY, 0);
				jornadaStop = competitionTable.indexOf(STOP_DAY, jornadaStart+START_DAY.length());
				
				// competition i jornada de div abans del table
				competition = competitionTable.substring(0, jornadaStart);
				day = competitionTable.substring(jornadaStart+START_DAY.length(), jornadaStop);
				
				int dayInt = 0;
				try 
				{
					// set day if to parsed days
					dayInt = Integer.parseInt(day);
				}
				catch(Exception e){}
				
				// afegim al array el header
				ContentValues headerValues = new ContentValues();
				headerValues.put(Supermanager.NextMatches.TYPE, 0);
				headerValues.put(Supermanager.NextMatches.MATCH_ORDER, 0);
				headerValues.put(Supermanager.NextMatches.COMPETITION, competition);
				headerValues.put(Supermanager.NextMatches.DAY, dayInt);
				headerValues.put(Supermanager.NextMatches.HOME_TEAM, "");
				headerValues.put(Supermanager.NextMatches.HOME_TEAM_ACRONYM, "");
				headerValues.put(Supermanager.NextMatches.VS_TEAM, "");
				headerValues.put(Supermanager.NextMatches.VS_TEAM_ACRONYM, "");
				headerValues.put(Supermanager.NextMatches.MATCH_DATE, 0);
				headerValues.put(Supermanager.NextMatches.RETRANSMISSIONS, "");
				
				matches.add(headerValues);
				
				days.add(dayInt);
				
				// agafem tr de partit
				trStart = competitionTable.indexOf(START_DAY_TR, jornadaStop+STOP_DAY.length());

				int order= 1;
				// mentres tinguem nous trs fem
				while( trStart != -1 )
				{
					// reset de variables
					homeTeam = "";
					vsTeam = "";
					matchDate = "";
					matchTime = "";
					matchTimestamp = null;
					retransmissionsTd = "";
					retransmissions = new ArrayList<String>();
					
					trStop = competitionTable.indexOf(STOP_DAY_TR, trStart+START_DAY_TR.length());
					String matchTr = competitionTable.substring(trStart+START_DAY_TR.length(), trStop);
					
					// teams td
					matchStart = matchTr.indexOf(START_TEAMS, 0);
					matchStop = matchTr.indexOf(STOP_TEAMS, matchStart+START_TEAMS.length());
					String teams = matchTr.substring(matchStart+START_TEAMS.length(), matchStop);
					homeTeam = teams.split(" - ")[0];
					vsTeam =teams.split(" - ")[1];
					
					// date
					dateStart = matchTr.indexOf(START_DATE, matchStop+STOP_TEAMS.length());
					dateStop = matchTr.indexOf(STOP_DATE, dateStart+START_DATE.length());
					matchDate = matchTr.substring(dateStart+START_DATE.length(), dateStop);
					
					// time 
					timeStart = matchTr.indexOf(START_TIME, dateStop+STOP_DATE.length());
					timeStop = matchTr.indexOf(STOP_TIME, timeStart+START_TIME.length());
					matchTime = matchTr.substring(timeStart+START_TIME.length(), timeStop);
					
					Pattern p = Pattern.compile("([^\\s]*)\\s([^\\/]*)\\/([^\\/]*)\\/([^\\s]*)\\s([^:]*):(.*)");
					Matcher m = p.matcher(matchDate+" "+matchTime);
					
					Calendar now = new GregorianCalendar();
					int any=now.get(Calendar.YEAR), 
						mes=now.get(Calendar.MONTH), 
						dia=now.get(Calendar.DAY_OF_MONTH), 
						hora=now.get(Calendar.HOUR_OF_DAY), 
						minuts=now.get(Calendar.MINUTE);
					if( m.find() ) 
					{	try
						{
							dia = Integer.parseInt(m.group(2));
							mes = Integer.parseInt(m.group(3));
							any = Integer.parseInt(m.group(4));
							hora = Integer.parseInt(m.group(5));
							minuts = Integer.parseInt(m.group(6));
						}
						catch(Exception e){}
					}
					
					Calendar calendar = new GregorianCalendar(any,mes-1,dia,hora,minuts);
					matchTimestamp = new Timestamp(calendar.getTimeInMillis());
					
					// retransmissions
					retransmissionStart = matchTr.indexOf(START_RETRANSMISSIONS, timeStop+STOP_TIME.length());
					retransmissionStop = matchTr.indexOf(STOP_RETRANSMISSIONS, retransmissionStart+START_RETRANSMISSIONS.length());
					retransmissionsTd = matchTr.substring(retransmissionStart+START_RETRANSMISSIONS.length(), retransmissionStop);
					
					// mentre tinguem retransmission
					retransmissionBStart = retransmissionsTd.indexOf(START_RETRANSMISSION_B);
					while( retransmissionBStart != -1 ) 
					{
						retransmissionBStop = retransmissionsTd.indexOf(STOP_RETRANSMISSION_B, retransmissionBStart+START_RETRANSMISSION_B.length());
						String tv = retransmissionsTd.substring(retransmissionBStart+START_RETRANSMISSION_B.length(), retransmissionBStop);
						
						retransmissions.add(tv);
						
						// nova retransmissio
						retransmissionBStart = retransmissionsTd.indexOf(START_RETRANSMISSION_B, retransmissionBStop+STOP_RETRANSMISSION_B.length());
					}
					
					// afegim al array 
					ContentValues values = new ContentValues();
					values.put(Supermanager.NextMatches.TYPE, 1);
					values.put(Supermanager.NextMatches.MATCH_ORDER, order++);
					values.put(Supermanager.NextMatches.COMPETITION, competition);
					values.put(Supermanager.NextMatches.DAY, dayInt);
					values.put(Supermanager.NextMatches.HOME_TEAM, homeTeam);
					String homeTeamAcronym = teamNameToAcronim.get(homeTeam);
					values.put(Supermanager.NextMatches.HOME_TEAM_ACRONYM, homeTeamAcronym);
					values.put(Supermanager.NextMatches.VS_TEAM, vsTeam);
					String vsTeamAcronym = teamNameToAcronim.get(vsTeam);
					values.put(Supermanager.NextMatches.VS_TEAM_ACRONYM, vsTeamAcronym);
					values.put(Supermanager.NextMatches.MATCH_DATE, matchTimestamp.getTime()/1000);
					values.put(Supermanager.NextMatches.RETRANSMISSIONS, StringUtils.join(retransmissions, ", "));
					
					// afegir values to insert 
					matches.add(values);
					
					// agafem nou tr de partit
					trStart = competitionTable.indexOf(START_DAY_TR, trStop+STOP_DAY.length());
				}
				
				// nova competition
				competitionStart = html.indexOf(START_COMPETITION_TABLE, competitionStop+STOP_COMPETITION_TABLE.length());
			}
		}
		catch(Exception e)
		{
			Log.d(Supermanager.TAG, "exception: "+e.getMessage());
		}
				
		return System.nanoTime()-start;
	}

	public ArrayList<ContentValues> getNextMatches() 
	{
		return matches;
	}
	
	public HashSet<Integer> getDayMatches()
	{
		return days;
	}
}

